import { IPSApplication } from '../../../app/ipsapplication';
import { IPSModelObject } from '../../../ipsmodel-object';
import { IPSModelService } from '../../../ipsmodel-service';

/**
 * 模型服务缓存帮助类
 *
 * @export
 * @class ModelServiceStore
 */
export class ModelServiceStore {
  /**
   * 忽略类型正则
   *
   * @author chitanda
   * @date 2021-04-10 11:04:41
   * @protected
   */
  protected modelCacheIgnoreReg = new RegExp(
    /^(app\.logic\.IPSAppUILogicRefView|control\.IPSControl|control\.form\.IPSDEEditForm)$/,
  );

  /**
   * 多语言缓存
   *
   * @author chitanda
   * @date 2021-05-27 16:05:29
   * @type {Map<string, string>}
   */
  readonly languageCache: Map<string, string> = new Map();

  /**
   * 模型服务缓存
   *
   * @type {Map<string, IPSModelService>}
   */
  readonly modelService: Map<string, IPSModelService> = new Map();

  /**
   * 模型对象换粗
   *
   * @type {Map<string, IPSModelObject>}
   */
  readonly modelObject: Map<string, IPSModelObject> = new Map();

  /**
   * 视图标识与路径对应表
   *
   * @type {Map<string, string>} <实体+视图名称, 路径>
   */
  readonly viewTagPath: Map<string, string> = new Map();

  /**
   * 视图路径对应应用模型缓存
   *
   * @type {Map<string, IModel>}
   */
  readonly viewPath: Map<string, IModel> = new Map();

  /**
   * 实体路径对应应用模型缓存
   *
   * @type {Map<string, IModel>}
   */
  readonly entityPath: Map<string, IModel> = new Map();

  /**
   * 代码表路径对应应用模型缓存
   *
   * @type {Map<string, IModel>}
   */
  readonly codeListPath: Map<string, IModel | IPSModelObject> = new Map();

  /**
   * 应用功能缓存
   *
   * @author chitanda
   * @date 2021-04-07 20:04:11
   * @type {Map<string, IModel>}
   */
  readonly appFuncs: Map<string, IModel | IPSModelObject> = new Map();

  /**
   * 全局实体行为缓存
   *
   * @author chitanda
   * @date 2021-04-07 20:04:02
   * @type {Map<string, IModel>}
   */
  readonly appDEUIAction: Map<string, IModel | IPSModelObject> = new Map();

  /**
   * 设置模型对象缓存
   *
   * @author chitanda
   * @date 2021-04-10 10:04:40
   * @param {string} cls
   * @param {string} key
   * @param {IPSModelObject} modelObject
   */
  setModelCache(cls: string, key: string, modelObject: IPSModelObject): void {
    if (this.cacheIgnore(cls)) {
      return;
    }
    this.modelObject.set(key, modelObject);
  }

  /**
   * 忽略缓存的类型
   *
   * @author chitanda
   * @date 2021-04-10 10:04:34
   * @protected
   * @param {string} cls
   * @return {*}  {boolean}
   */
  protected cacheIgnore(cls: string): boolean {
    if (this.modelCacheIgnoreReg.test(cls)) {
      return true;
    }
    return false;
  }

  /**
   * 填充视图标识与路径对应
   *
   * @param {IPSApplication} app
   */
  fillViewTagPath(app: IPSApplication): void {
    if (app && this.viewTagPath.size === 0) {
      const models = app.M.getAllPSAppViews;
      if (models && models.length > 0) {
        models.forEach((item: any) => {
          const str =
            (item.resource || '').toLowerCase() +
            (item.view || '').toLowerCase();
          this.viewTagPath.set(str, item.path);
        });
      }
    }
  }

  /**
   * 填充应用视图路径对应模型
   *
   * @param {IPSApplication} app
   */
  fillViewPath(app: IPSApplication): void {
    if (app) {
      this.fillMapCache(app.M.getAllPSAppViews, this.viewPath);
    }
  }

  /**
   * 填充应用实体路径对应模型
   *
   * @param {IPSApplication} app
   */
  fillEntityPath(app: IPSApplication): void {
    if (app) {
      this.fillMapCache(app.M.getAllPSAppDataEntities, this.entityPath);
    }
  }

  /**
   * 填充代码表路径对应模型
   *
   * @param {IPSApplication} app
   */
  fillCodeListPath(app: IPSApplication): void {
    if (app) {
      this.fillMapCache(app.M.getAllPSAppCodeLists, this.codeListPath);
    }
  }

  /**
   * 填充应用功能缓存，使用CodeName
   *
   * @author chitanda
   * @date 2021-04-07 20:04:07
   * @param {IPSApplication} app
   */
  fillAppFuncs(app: IPSApplication): void {
    if (app) {
      this.fillMapCacheByCodeName(app.M.getAllPSAppFuncs, this.appFuncs);
    }
  }

  /**
   * 填充应用实体界面行为缓存，使用CodeName
   *
   * @author chitanda
   * @date 2021-04-07 20:04:21
   * @param {IPSApplication} app
   */
  fillAppDEUIActions(app: IPSApplication): void {
    if (app) {
      this.fillMapCacheByCodeName(
        app.M.getAllPSAppDEUIActions,
        this.appDEUIAction,
      );
    }
  }

  /**
   * 填充Map缓存
   *
   * @protected
   * @param {IModel[]} models
   * @param {Map<string, unknown>} cache
   */
  protected fillMapCache(models: IModel[], cache: Map<string, unknown>): void {
    if (cache.size === 0 && models && models.length > 0) {
      models.forEach((item: any) => {
        cache.set(this.getPath(item), item);
      });
    }
  }

  /**
   * 填充Map缓存
   *
   * @protected
   * @param {IModel[]} models
   * @param {Map<string, unknown>} cache
   */
  protected fillMapCacheByCodeName(
    models: IModel[],
    cache: Map<string, unknown>,
  ): void {
    if (cache.size === 0 && models && models.length > 0) {
      models.forEach((item: any) => {
        cache.set(item.codeName, item);
      });
    }
  }

  /**
   * 获取模型路径
   *
   * @protected
   * @param {IModel} model
   * @return {*}  {string}
   */
  protected getPath(model: IModel): string {
    return model.path || model.dynaModelFilePath;
  }

  /**
   * 清理缓存
   *
   * @author chitanda
   * @date 2021-05-20 00:05:57
   */
  clear(): void {
    this.modelService.clear();
    this.modelObject.clear();
    this.viewTagPath.clear();
    this.viewPath.clear();
    this.entityPath.clear();
    this.codeListPath.clear();
    this.appFuncs.clear();
    this.appDEUIAction.clear();
  }
}
